﻿using DotNetImage.Types;
using System;
using System.Windows;

namespace DotNetImage.Imaging.Filters
{
    public class Water<TPixel, TColorChannel> : FilterBase
    {
        FloatPoint[,] floatingPoints = null;
        Point[,] points = null;
        Point mid = new Point();

        [ParameterAttribute(Name = "Wave", DefaultValue = 0, MinValue = 0, MaxValue = short.MaxValue, Step = 1)]
        public short Wave { get; set; }
        public bool Smoothing { get; set; }


        protected override void PrepareData(DotNetImage bmp)
        {
            bmp.CreatePixelCopy();
            points = new Point[nWidth, nHeight];
            floatingPoints = new FloatPoint[nWidth, nHeight];
            mid.X = nWidth / 2;
            mid.Y = nHeight / 2;
        }

        protected override void ProcessPixel(ref Pixel pix, uint x, uint y)
        {
            double xo = ((double)Wave * Math.Sin(2.0 * 3.1415 * (float)y / 128.0));
            double yo = ((double)Wave * Math.Cos(2.0 * 3.1415 * (float)x / 128.0));

            double newX = (x + xo);
            double newY = (y + yo);

            if (newX > 0 && newX < nWidth)
            {
                floatingPoints[x, y].X = newX;
                points[x, y].X = (int)newX;
            }
            else
            {
                floatingPoints[x, y].X = 0.0;
                points[x, y].X = 0;
            }


            if (newY > 0 && newY < nHeight)
            {
                floatingPoints[x, y].Y = newY;
                points[x, y].Y = (int)newY;
            }
            else
            {
                floatingPoints[x, y].Y = 0.0;
                points[x, y].Y = 0;
            }
        }

        protected override void PostProcessing(DotNetImage bmp)
        {
            base.PostProcessing(bmp);
            if (Smoothing)
            {
                OffsetFilterAntiAlias filter = new OffsetFilterAntiAlias();
                filter.Offset = floatingPoints;
                filter.Apply(bmp);
            }
            else
            {
                OffsetFilterAbs filter = new OffsetFilterAbs();
                filter.Offset = points;
                filter.Apply(bmp);
            }
        }
    }
}
